/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#ifndef DEV_NCSI_PROTOCOL_H
#define DEV_NCSI_PROTOCOL_H

#ifdef __cplusplus
extern "C" {
#endif

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>

#include <ncsi/adapter.h>

#define ETH_NAME_LEN    16 // IFNAMSIZ
#define MAX_MAC_STR_LEN 32 /* mac地址的字符串形式最大长度 */

#ifndef NCSI_MAC_LEN
#define NCSI_MAC_LEN 6
#endif

#define USERFULL   1
#define UN_USEFULL 0
#define NCSI_OK    0
#define NCSI_FALSE 1
#define NCSI_ERR   (-1)
#define NCSI_MCID  0

#ifndef MAX_ETH_NUM
#define MAX_ETH_NUM 16
#endif

#ifndef MAC_ADDR_BYTES_NUM
#define MAC_ADDR_BYTES_NUM 6
#endif

#ifndef MAX_PCIE_MAC_NUM
#define MAX_PCIE_MAC_NUM 8 /* 最多8个MAC */
#endif

#define AEN_DISABLE 0
/* Command-Specific Reason Codes */
#define LINK_ACCESS_ERROR   6
#define MAC_ADDRESS_IS_ZEOR 8
#define ETH_SEND_FAIL       0xFFFF
#define ETH_NCSI_TYPE       0x88F8

#define CHANNEL_SUPPORT     1
#define PACKAGE_SUPPORT     1
#define ARBITRATION_ENABLE  0
#define ARBITRATION_DISABLE 1

/* NCSI Standard Reason Code Values
0x0000 When used with the Command Completed response code, indicates that the command completed
normally. Otherwise this value indicates that no additional reason code information is being
provided. 0x0001 Returned for all commands when the channel is in the Initial State, until the
channel receives a Clear Initial State command 0x0002 Returned when a received parameter value is
outside of the acceptable values for that parameter 0x0003 May be returned when the channel is in a
transient state in which it is unable to process commands normally 0x0004 May be returned when the
package and channels within the package are in a transient state in which normal command processing
cannot be done 0x0005  The payload length in the command is incorrect for the given command 0x7FFF
Unknown / Unsupported Command Type */
#define NOERROR_OR_NOREASON      0x0000
#define INTERFACE_INIT_REQUIRED  0x0001
#define PARAMETER_INVALID        0x0002
#define CHANNEL_NOT_READY        0x0003
#define PACKAGE_NOT_READY        0x0004
#define INVALID_PAYLOAD_LENGTH   0x0005
#define UNSUPPORTED_COMMAND_TYPE 0x7FFF

/* NCSI命令集 */
/* Used by the Management Controller to acknowledge that the Network Controller is in the Initial
 * State */
#define CLEAR_INITIAL_STATE     0x00
#define CLEAR_INITIAL_STATE_RSP 0x80

/* Used to explicitly select a controller package to transmit packets through the NC-SI interface */
#define SELECT_PACKAGE     0x01
#define SELECT_PACKAGE_RSP 0x81

/* Used to explicitly instruct the controller package to stop transmitting packets through the NC-SI
 * interface */
#define DESELECT_PACKAGE     0x02
#define DESELECT_PACKAGE_RSP 0x82

/* Used to enable the NC-SI channel and to cause the forwarding of bidirectional Management
 * Controller packets to start
 */
#define ENABLE_CHANNEL     0x03
#define ENABLE_CHANNEL_RSP 0x83

/* disable the NC-SI channel and to cause the forwarding of bidirectional Management Controller
 * packets to cease */
#define DISABLE_CHANNEL     0x04
#define DISABLE_CHANNEL_RSP 0x84

/* synchronously put the Network Controller back to the Initial State */
#define RESEET_CHANNEL     0x05
#define RESEET_CHANNEL_RSP 0x85

/* enable the channel to transmit Pass-through packets onto the network */
#define ENABLE_CHANNEL_TX     0x06
#define ENABLE_CHANNEL_TX_RSP 0x86

/* disable the channel from transmitting Pass-through packets onto the network */
#define DISABLE_CHANNEL_TX     0x07
#define DISABLE_CHANNEL_TX_RSP 0x87

/* Used to control generating AENs */
#define AEN_ENABLE_REQ 0x08
#define AEN_ENABLE_RSP 0x88

/* during OS absence to force link settings, or to return to auto-negotiation mode */
#define SET_LINK     0x09
#define SET_LINK_RSP 0x89

/* get current link status information */
#define GET_LINK_STATUS     0x0A
#define GET_LINK_STATUS_RSP 0x8A

/* program VLAN IDs for VLAN filtering */
#define SET_VLAN_FILTER     0x0B
#define SET_VLAN_FILTER_RSP 0x8B

/* enable the channel to accept VLAN-tagged packets from the network for NC-SI Pass-through
 * operation */
#define ENABLE_VLAN_REQ 0x0C
#define ENABLE_VLAN_RSP 0x8C

/* disable VLAN filtering */
#define DISABLE_VLAN_REQ 0x0D
#define DISABLE_VLAN_RSP 0x8D

/* program the channel’s unicast or multicast MAC address filters */
#define SET_MAC_ADDRESS     0x0E
#define SET_MAC_ADDRESS_RSP 0x8E

/* Controller to control the forwarding of broadcast frames to the Management Controller. */
#define ENABLE_BROADCAST_FILTER     0x10
#define ENABLE_BROADCAST_FILTER_RSP 0x90

/* disable all broadcast packet filtering, and to enable the forwarding of broadcast packets */
#define DISABLE_BRDCST_FILTER     0x11
#define DISABLE_BRDCST_FILTER_RSP 0x91

/* disable forwarding of all multicast packets to the Management Controller */
#define ENABLE_MULTICAST_FILTER     0x12
#define ENABLE_MULTICAST_FILTER_RSP 0x92

/* enable forwarding of all multicast packets to the Management Controller */
#define DISABLE_MULTICAST_FILTER     0x13
#define DISABLE_MULTICAST_FILTER_RSP 0x93

/* Used to get controller-related version information */
#define GET_VERSION_ID     0x15
#define GET_VERSION_ID_RSP 0x95

/* Used to get optional functions supported by the NC-SI */
#define GET_CAPABILITIES     0x16
#define GET_CAPABILITIES_RSP 0x96

/* Used to get parameters */
#define GET_PARAMETERS     0x17
#define GET_PARAMETERS_RSP 0x97

/* Used to get controller packet statistics */
#define GET_CONTROLLER_PACKET_STATISTICS     0x18
#define GET_CONTROLLER_PACKET_STATISTICS_RSP 0x98

/* request vendor-specific data */
#define OEM_COMMAND     0x50
#define OEM_COMMAND_RSP 0xD0

#define SET_LLDP_OVER_NCSI_STATUS 0x0A
#define GET_LLDP_OVER_NCSI_STATUS 0x0B
#define SET_LLDP_OVER_NCSI_CMD_ID 0x04
#define GET_LLDP_OVER_NCSI_CMD_ID 0x04

#define GET_FACTORY_DEFAULT_MAC_SUB_CMD 0x04
#define GET_FACTORY_DEFAULT_MAC_CMD_ID  0x01

#define GET_HW_OEM_CMD_CAP_SUB_CMD 0x11 /* Sub Comman ID: Get HW OEM command capability */
#define GET_CONTROLLER_INFO_CMD_ID 0x00 /* HW Command ID: Inquire controller information */

#define GET_NETCARD_TEMP_SUB_CMD 0x0A
#define GET_NETCARD_TEMP_CMD_ID  0x00

#define GET_LOG_SUB_CMD_NEW 0x16
#define GET_LOG_SUB_CMD     0x15
#define GET_LOG_CMD_ID      0x00

#define NCSI_PACKAGE0    0
#define NCSI_NOT_SUPPORT 0

#ifdef BD_BIG_ENDIAN
#define SHORT_BY_BIG_ENDIAN(x) (x)
#else
#define SHORT_BY_BIG_ENDIAN(s) ((uint16_t)((s) >> 8) | (uint16_t)((s) << 8))
#endif

/* NCSI Standard Response Code
0x0  Returned for a successful command completion
0x1  Returned to report that a valid command could not be processed or failed to complete correctly
0x2  Returned to report that a command is temporarily unavailable for execution because the
     controller is in a transient state or busy condition
0x3  Returned to report that a command is not supported by the implementation */
#define COMMAND_COMPLETED   0x0000
#define COMMAND_FAILED      0x0001
#define COMMAND_UNAVAILABLE 0x0002
#define COMMAND_UNSUPPORTED 0x0003

#pragma pack(1)

/* Clear Initial State Command (0x00) */
/* Payload length does not include the length of the NC-SI header, the
checksum value, or any padding that might be present. */
#define CLEAR_INITIAL_REQ_LEN      0
#define CLEAR_INITIAL_RSP_LEN      4
#define HUAWEI_OEM_PAYLOAD_MAX_LEN 64

typedef struct tg_huawei_oem_ncsi_pkg_req {
    uint32_t manufacture_id;
    uint8_t  cmd_rev;
    uint8_t  cmd_id;
    uint8_t  sub_cmd;
    uint8_t  reserved;
    uint8_t payload[HUAWEI_OEM_PAYLOAD_MAX_LEN]; /* payload中包含有效负载和check_sum，由于Huawei OEM
                                                   NCSI命令中check
                                                   sum所在的位置不固定，因此无法单独定义checksum */
} hw_oem_ncsi_pkg_req, *p_hw_oem_ncsi_pkg_req;

typedef struct tg_huawei_oem_ncsi_pkg_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t manufacture_id;
    uint8_t  cmd_rev;
    uint8_t  cmd_id;
    uint8_t  sub_cmd;
    uint8_t  reserved;
    uint8_t payload[HUAWEI_OEM_PAYLOAD_MAX_LEN]; /* payload中包含有效负载和check_sum，由于Huawei OEM
                                                   NCSI命令中check
                                                   sum所在的位置不固定，因此无法单独定义checksum */
} hw_oem_ncsi_pkg_rsp, *p_hw_oem_ncsi_pkg_rsp;

#ifndef LLDP_OVER_NCSI_RESERVED_BYTES
#define LLDP_OVER_NCSI_RESERVED_BYTES 3
#endif
typedef struct tag_set_lldp_over_ncsi {
    uint8_t  status;
    uint8_t  reserved[LLDP_OVER_NCSI_RESERVED_BYTES];
    uint32_t check_sum; /* 此处check sum是整个NCSI报文的check_sum，但由于整个Huawei OEM
                          NCSI报文的长度不固定，
                          check_sum在整个报文中的位置也不确定，因此只能把checksum放到最后的payload里
                        */
} set_lldp_over_ncsi_req, *p_set_lldp_over_ncsi_req;

typedef struct tag_get_netcard_temp_rsp {
    uint16_t temp;
    uint16_t reserved;
    uint32_t check_sum;
} get_netcard_temp_rsp, *p_get_netcard_temp_rsp;

/* Get Capabilities Command (0x16) */
#define GET_CAPABILITIES_REQ_LEN 0
#define GET_CAPABILITIES_RSP_LEN 32
#define GET_CAPABILITIES_PAD_LEN 26

#define VLAN_MODE_FIELD_VLAN_ONLY        0x01
#define VLAN_MODE_FIELD_VLAN_NON_VLAN    0x02
#define VLAN_MODE_FIELD_ANYVLAN_NON_VLAN 0x04

typedef struct tg_get_capability {
    uint32_t check_sum;
    uint8_t  pad_data[GET_CAPABILITIES_PAD_LEN];
    uint32_t FCS;
} get_capability, *p_get_capability;

typedef struct tg_get_capability_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t capality_flag;
    uint32_t broadcast_filter_cap;
    uint32_t multicast_filter_cap;
    uint32_t buffer_cap;
    uint32_t aen_support;
    uint8_t  vlan_filter_cnt;
    uint8_t  mix_filter_cnt;
    uint8_t  mul_filter_cnt;
    uint8_t  unicast_filter_cnt;
    uint8_t  reserved[2];
    uint8_t  vlan_mode;
    uint8_t  channel_cnt;
    uint32_t check_sum;
    uint32_t FCS;
} get_capability_rsp, *p_get_capability_rsp;

#define GET_PARAMETERS_RSP_LEN 40

typedef struct tg_get_parameters_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint8_t  mac_cnt;
    uint8_t  reserved[2];
    uint8_t  mac_enable;
    uint8_t  vlan_cnt;
    uint8_t  reserved1;
    uint16_t vlan_enable;
    uint32_t link_mode;
    uint32_t bc_mode;
    uint32_t valid_modes;
    uint8_t  vlan_mode;
    uint8_t  fc_mode;
    uint8_t  reserved2[2];
    uint32_t aen_mode;
    uint8_t  mac[6];
    uint16_t vlan;
    uint32_t check_sum;
    uint32_t FCS;
} get_parameters_rsp, *p_get_parameters_rsp;

/* Deselect Package Command (0x02)  */
#define DESELECT_PACKAGE_REQ_LEN     0
#define DESELECT_PACKAGE_RSP_LEN     4
#define DESELECT_PACKAGE_REQ_PAD_LEN 26
#define DESELECT_PACKAGE_RSP_PAD_LEN 22

typedef struct tg_deselect_package {
    uint32_t check_sum;
    uint8_t  pad_data[DESELECT_PACKAGE_REQ_PAD_LEN];
    uint32_t FCS;
} deselect_package, *p_deselect_package;
/* Deselect Package Response (0x82)  */
typedef struct tg_deselect_package_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[DESELECT_PACKAGE_RSP_PAD_LEN];
    uint32_t FCS;
} deselect_package_rsp, *p_deselect_package_rsp;

/* Enable Channel Command (0x03)  */
#define ENABLE_CHANNEL_REQ_LEN     0
#define ENABLE_CHANNEL_RSP_LEN     4
#define ENABLE_CHANNEL_REQ_PAD_LEN 26
#define ENABLE_CHANNEL_RSP_PAD_LEN 22

typedef struct tg_enable_channel {
    uint32_t check_sum;
    uint8_t  pad_data[ENABLE_CHANNEL_REQ_PAD_LEN];
    uint32_t FCS;
} enable_channel, *p_enable_channel;
/* Enable Channel Response (0x83) */
typedef struct tg_enable_channel_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[ENABLE_CHANNEL_RSP_PAD_LEN];
    uint32_t FCS;
} enable_channel_rsp, *p_enable_channel_rsp;

/* Disabled Channel Command (0x04)  */
#define DISABLE_CHANNEL_REQ_LEN     4
#define DISABLE_CHANNEL_RSP_LEN     4
#define DISABLE_CHANNEL_REQ_PAD_LEN 22
#define DISABLE_CHANNEL_RSP_PAD_LEN 22

typedef struct tg_disenable_channel {
#ifdef BD_BIG_ENDIAN
    uint32_t reserved        : 31;
    uint8_t  allow_link_down : 1;
#else
    uint8_t  allow_link_down : 1;
    uint32_t reserved        : 31;
#endif

    uint32_t check_sum;
    uint8_t  pad_data[DISABLE_CHANNEL_REQ_PAD_LEN];
    uint32_t FCS;
} disenable_channel, *p_disenable_channel;
/* Disabled Channel Response (0x84) */
typedef struct tg_disenable_channel_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[DISABLE_CHANNEL_RSP_PAD_LEN];
    uint32_t FCS;
} disenable_channel_rsp, *p_disenable_channel_rsp;

/* Enable VLAN Command (0x0C)   */
#define ENABLE_VLAN_REQ_LEN     4
#define ENABLE_VLAN_RSP_LEN     4
#define ENABLE_VLAN_REQ_PAD_LEN 22
#define ENABLE_VLAN_RSP_PAD_LEN 22

/* VLAN mode */
/* Only VLAN-tagged packets that match the enabled VLAN Filter settings are accepted. */
#define VLAN_ONLY 0x01
/* VLAN-tagged packets that match the enabled VLAN Filter settings are accepted */
#define VLAN_NON_VLAN 0x02
/* Any VLAN-tagged packets that also match the MAC Address
Filtering configuration are accepted, regardless of the VLAN Filter settings.
Non-VLAN-tagged packets are also accepted. */
#define ANYVLAN_NON_VLAN 0x03

typedef struct tg_enable_vlan {
    uint8_t  reserved[3];
    uint8_t  vlan_mode;
    uint32_t check_sum;
    uint8_t  pad_data[ENABLE_VLAN_REQ_PAD_LEN];
    uint32_t FCS;
} enable_vlan, *p_enable_vlan;
/* Enable VLAN Response (0x8C)   */
typedef struct tg_enable_vlan_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[ENABLE_VLAN_RSP_PAD_LEN];
    uint32_t FCS;
} enable_vlan_rsp, *p_enable_vlan_rsp;

/* Disable VLAN Command (0x0D)   */
#define DISABLE_VLAN_REQ_LEN     0
#define DISABLE_VLAN_RSP_LEN     4
#define DISABLE_VLAN_REQ_PAD_LEN 26
#define DISABLE_VLAN_RSP_PAD_LEN 22

typedef struct tg_disable_vlan {
    uint32_t check_sum;
    uint8_t  pad_data[DISABLE_VLAN_REQ_PAD_LEN];
    uint32_t FCS;
} disable_vlan, *p_disable_vlan;
/* Disable VLAN Response (0x8D  */
typedef struct tg_disable_vlan_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[DISABLE_VLAN_RSP_PAD_LEN];
    uint32_t FCS;
} disable_vlan_rsp, *p_disable_vlan_rsp;

/* Set MAC Address Command (0x0E)  */
#define MAC_FILTER_ENABLE  1 // Enable this MAC address filter
#define MAC_FILTER_DISABLE 0 // Disable this MAC address filter

#define UNICAST_MAC_ADDRESS   0 // Unicast MAC address
#define MULTICAST_MAC_ADDRESS 1 // Multicast MAC address

#define SET_MAC_ADDRESS_REQ_LEN 8
#define SET_MAC_ADDRESS_RSP_LEN 4

#define SET_MAC_ADDRESS_RSP_PAD_LEN 22

/* VLAN ID */
#define SET_VLAN_FILTER_REQ_LEN 8
#define SET_VLAN_FILTER_RSP_LEN 4

#define SET_VLAN_FILTER_RSP_PAD_LEN 22

/* Set Vlan Filter Response (0x8B)  */
typedef struct tg_set_vlan_filter_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[SET_VLAN_FILTER_RSP_PAD_LEN];
    uint32_t FCS;
} set_vlan_filter_rsp, *p_set_vlan_filter_rsp;

/* Set MAC Address Response (0x8E)  */
typedef struct tg_set_mac_address_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[SET_MAC_ADDRESS_RSP_PAD_LEN];
    uint32_t FCS;
} set_mac_address_rsp, *p_set_mac_address_rsp;

/* Enable Broadcast Filter Command (0x10) */
#define ENABLE_BROADFILTER_REQ_LEN 4
#define ENABLE_BROADFILTER_RSP_LEN 4

/* Enable Channel Network TX Command (0x06) */
#define ENABLE_CHN_TX_REQ_LEN     0
#define ENABLE_CHN_TX_RSP_LEN     4
#define ENABLE_CHN_TX_REQ_PAD_LEN 26
#define ENABLE_CHN_TX_RSP_PAD_LEN 22

typedef struct tg_enable_chn_tx {
    uint32_t check_sum;
    uint8_t  pad_data[ENABLE_CHN_TX_REQ_PAD_LEN];
    uint32_t FCS;
} enable_chn_tx, *p_enable_chn_tx;
/*  Enable Channel Network TX Response (0x86) ) */
typedef struct tg_enable_chn_tx_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[ENABLE_CHN_TX_RSP_PAD_LEN];
    uint32_t FCS;
} enable_chn_tx_rsp, *p_enable_chn_tx_rsp;

/* Disable Channel Network TX Command (0x07) */
#define DISABLE_CHN_TX_REQ_LEN     0
#define DISABLE_CHN_TX_RSP_LEN     4
#define DISABLE_CHN_TX_REQ_PAD_LEN 26
#define DISABLE_CHN_TX_RSP_PAD_LEN 22

typedef struct tg_disable_chn_tx {
    uint32_t check_sum;
    uint8_t  pad_data[DISABLE_CHN_TX_REQ_PAD_LEN];
    uint32_t FCS;
} disable_chn_tx, *p_disable_chn_tx;
/*  Enable Channel Network TX Response (0x87) ) */
typedef struct tg_disable_chn_tx_rsp {
    uint16_t rsp_code;
    uint16_t reason_code;
    uint32_t check_sum;
    uint8_t  pad_data[DISABLE_CHN_TX_RSP_PAD_LEN];
    uint32_t FCS;
} disable_chn_tx_rsp, *p_disable_chn_tx_rsp;

/* Get Link Status Command (0x0A) */
#define GET_LINK_STATUS_REQ_LEN     0
#define GET_LINK_STATUS_RSP_LEN     16
#define GET_LINK_STATUS_REQ_PAD_LEN 26

typedef struct tg_link_status {
    uint32_t check_sum;
    uint8_t  pad_data[GET_LINK_STATUS_REQ_PAD_LEN];
    uint32_t FCS;
} link_status, *p_link_status;

typedef struct tag_hw_oem_cmd_capability {
    uint8_t reserved_byte1;
    uint8_t reserved_byte2;
    uint8_t reserved_byte3;
#ifdef BD_BIG_ENDIAN
    uint32_t reserved_bits      : 4; /* other reserved bits */
    uint32_t lldp_forward_get   : 1; /* bit3: Get LLDP forward over NCSI status */
    uint32_t lldp_forward_set   : 1; /* bit2: Enable/disable LLDP forward over NCSI */
    uint32_t low_power_mode_get : 1; /* bit1: Get low power consumption mode */
    uint32_t low_power_mode_set : 1; /* bit0: Enable/disable low power consumption mode */
#else
    uint32_t low_power_mode_set : 1; /* bit0: Enable/disable low power consumption mode */
    uint32_t low_power_mode_get : 1; /* bit1: Get low power consumption mode */
    uint32_t lldp_forward_set   : 1; /* bit2: Enable/disable LLDP forward over NCSI */
    uint32_t lldp_forward_get   : 1; /* bit3: Get LLDP forward over NCSI status */
    uint32_t reserved_bits      : 4; /* other reserved bits */
#endif
} hw_oem_cmd_capability;
typedef union tag_hw_oem_cmd_cap {
    hw_oem_cmd_capability cap_bits;
    uint32_t              cap_u32;
} hw_oem_cmd_cap;
#define HW_OEM_CMD_CAP_RESERVED_BYTES 52
typedef struct tag_get_hw_oem_cmd_cap_rsp {
    hw_oem_cmd_cap capability;
    uint8_t        reserved[HW_OEM_CMD_CAP_RESERVED_BYTES];
    uint32_t       check_sum;
} get_hw_oem_cmd_cap_rsp, *p_get_hw_oem_cmd_cap_rsp;

/* NC-SI */
#define NCSI_ENABLED               1
#define NCSI_UNENABLED             0
#define NCSI_CHANNEL_AVAILABLE     1
#define NCSI_CHANNEL_NOT_AVAILABLE 0

typedef struct tag_mac_addr_param {
    uint8_t mac_addr[NCSI_MAC_LEN];
    uint8_t mac_addr_len;
    uint8_t mac_addr_num; // MAC地址过滤器的编号，从1开始
    uint8_t addr_type;    // MAC地址过滤器类型
    uint8_t mac_enable;   // MAC地址过滤器使能状态
} mac_addr_param, *pmac_addr_param;

typedef struct tag_get_log_over_ncsi {
    uint32_t offset;
    uint32_t length;
    uint32_t check_sum;
} get_log_over_ncsi_req, *p_get_log_over_ncsi_req;

typedef struct tag_get_log_over_ncsi_new {
    uint32_t frame_type;
    uint32_t offset;
    uint32_t length;
    uint32_t check_sum;
} get_log_over_ncsi_req_new, *p_get_log_over_ncsi_req_new;

#define SDI_NCSI_CMD_READ_BLOCK 1024
typedef struct tag_get_log_over_ncsi_rsp {
    uint8_t  data[SDI_NCSI_CMD_READ_BLOCK];
    uint32_t check_sum;
} get_log_over_ncsi_rsp, *p_get_log_over_ncsi_rsp;

#define MAX_SUB_LOG 255
typedef struct tag_get_log_over_ncsi_rsp_control {
    uint32_t total_len;
    uint8_t  sub_log_num;
    uint8_t  reserved;
    uint16_t
        data[MAX_SUB_LOG + 2]; // 不知道子日志具体个数，check_sum无法确定具体位置，此处无法单独声明
} get_log_over_ncsi_rsp_control, *p_get_log_over_ncsi_rsp_control;

#define RESERVED_LEN 3
typedef struct tag_get_log_over_ncsi_rsp_data {
    uint8_t  last_frame;
    uint8_t  reserved[RESERVED_LEN];
    uint16_t data[SDI_NCSI_CMD_READ_BLOCK + 4]; // 最后帧长度是不确定的，按最大长度接收
} get_log_over_ncsi_rsp_data, *p_get_log_over_ncsi_rsp_data;

typedef struct tag_log_file_type {
    uint8_t type;
    char*   name;
} log_file_type, *p_log_file_type;

// NCSI日志缓存最大长度，当超过64KB，或最后一帧写入文件
#define MAX_BUFFER_LEN (64 * 1024)
typedef struct tag_log_context {
    // 日志总长，单位KB
    uint32_t total_length;
    // 子日志个数
    uint8_t sub_log_num;
    // 控制帧标志，1表示控制帧
    uint8_t is_control_frame;
    // 子日志长度数组
    uint16_t sub_log_lens[MAX_SUB_LOG];
    // 1表示最后一帧
    uint8_t last_frame;
    // 日志内容缓存
    uint8_t data_buffer[MAX_BUFFER_LEN];
    // 日志内容缓存已写入大小，单位byte
    uint32_t data_buffer_content_size;
    // log type已收集日志大小，单位byte
    uint32_t cur_len;
    // 子日志已收集日志大小，用来计算补0大小，单位byte
    uint32_t sub_cur_len;
    // 当前正在收集的子日志序号
    uint8_t sub_log_idx;
} log_context, *p_log_context;

#pragma pack()

typedef enum {
    MAC_FILTER_NUM_PHYSICAL = 1 // 命令字段中MAC Addr Number域的值从1开始
} MAC_FILTER_NUM;

#define HUAWEI_MANUFACTURE_ID 0xdb070000

#ifdef __cplusplus
}
#endif

#endif // DEV_NCSI_PROTOCOL_H
